package academic.ui.client.presenter;


import academic.ui.client.AppServiceAsync;
import academic.ui.client.CheckoutServiceAsync;
import academic.ui.client.place.Tokens;
import academic.ui.client.rules.Rules;
import ecommerce.soco.shared.GWT_CreditCard;
import ecommerce.soco.shared.GWT_Customer;
import ecommerce.soco.shared.GWT_Gift;
import ecommerce.soco.shared.GWT_Product;
import ecommerce.soco.shared.GWT_Zone;

import com.allen_sauer.gwt.log.client.Log;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.shared.GwtEvent.Type;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.inject.Inject;
import com.gwtplatform.mvp.client.EventBus;
import com.gwtplatform.mvp.client.Presenter;
import com.gwtplatform.mvp.client.View;
import com.gwtplatform.mvp.client.annotations.ContentSlot;
import com.gwtplatform.mvp.client.annotations.NameToken;
import com.gwtplatform.mvp.client.annotations.ProxyStandard;
import com.gwtplatform.mvp.client.proxy.PlaceManager;
import com.gwtplatform.mvp.client.proxy.PlaceRequest;
import com.gwtplatform.mvp.client.proxy.ProxyPlace;
import com.gwtplatform.mvp.client.proxy.RevealContentEvent;
import com.gwtplatform.mvp.client.proxy.RevealContentHandler;

public class CheckoutPresenter extends Presenter<CheckoutPresenter.MyView,CheckoutPresenter.MyProxy>{

	public static String EVENT_SELECTOR ="createEvent";

	private String productID;

	private final CheckoutServiceAsync checkoutService;
	private final AppServiceAsync appService;
	private final int SAVECARDFAILURE = -1;
	public static final String SELECTOR = "checkoutWithGift"; 
	private PlaceManager placeManager;
	
	private CardPresenter cardPresenter;
	
	@ContentSlot
	public static final Type<RevealContentHandler<?>> slot = new Type<RevealContentHandler<?>>();
	
	
	@Inject
	public CheckoutPresenter(EventBus eventBus, MyView view, MyProxy proxy,CheckoutServiceAsync service,AppServiceAsync appService, CardPresenter cardPresenter, PlaceManager placeManager) {
		super(eventBus, view, proxy);
		this.checkoutService=service;
		this.appService=appService;
		this.placeManager=placeManager;
		this.cardPresenter = cardPresenter;
		
	}

	@ProxyStandard
	@NameToken(Tokens.checkout)
	public interface MyProxy extends ProxyPlace<CheckoutPresenter>  {}

	public interface MyView extends View {

		HasClickHandlers confirmOrder();

		void addZoneOptions(GWT_Zone[] zones);
		
		void setLoginError(String string);

		GWT_Customer getRegisterCustomer();
				
		//show checkout form
		void setupLoggedInNoCards();

		//user has no session display checkout w/ registration form
		void setupCheckoutRegistration();

		boolean checkCheckoutRegistrationRules();

		void showPurchase(GWT_Product result);

		HasClickHandlers getSignInLink();

		Integer getQuantity();

		void throwError(int lOGINERRORUSERNOTFOUND);
		
		Integer cardID();

		GWT_CreditCard getCard();

		void setupLoggedInWithCards();

		int getRadioId();

		GWT_Gift getGift();

		HasClickHandlers getBuyAsGiftLink();

		HasClickHandlers createEventLink();


	}

	@Override
	protected void revealInParent() {
		RevealContentEvent.fire(this, AppPresenter.slot, this);
		Log.debug("CheckoutPresenter revealInParent");
	}
	
	@Override
	public void prepareFromRequest( PlaceRequest request )
	{
		super.prepareFromRequest(request);
		productID=request.getParameter("id",null);		
	}
	
	@Override
	public void onBind() {
		super.onBind();
		Log.debug("CheckoutPresenter onBind");
		//confirm order button clicked
		registerHandler(getView().confirmOrder().addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				if(!getView().checkCheckoutRegistrationRules() && getView().getRadioId()<1) {
					Log.debug("checkout rules failed");
				}
				else 
				{
						Integer prodID = Integer.valueOf(productID);
						Integer quantity = getView().getQuantity();
						GWT_Customer customerRegister = getView().getRegisterCustomer();
						
						checkoutService.processOrder(prodID,quantity,customerRegister,getView().getCard(),getView().getGift(), new AsyncCallback<Integer>() {
							
							@Override
							public void onFailure(Throwable caught) {
								// TODO Auto-generated method stub
								
							}
	
							@Override
							public void onSuccess(Integer result) {
								if(result==Rules.SUCCESS)
								{
									placeManager.revealPlace(new PlaceRequest(Tokens.receipt).with("id",productID).with("quantity", String.valueOf(getView().getQuantity())));
								}
								else if(result==Rules.LOGIN_ERROR_USER_NOT_FOUND)
								{
									getView().throwError(Rules.LOGIN_ERROR_USER_NOT_FOUND);
								}
							}
							
						});				
					}
				}
								
		}));
		
	
		registerHandler(getView().getBuyAsGiftLink().addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				placeManager.revealPlace(new PlaceRequest(Tokens.gift).with("selector", "checkoutLoginLink"));
			}
			
		}));
	
		
		//sign in button clicked
		registerHandler(getView().getSignInLink().addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				placeManager.revealPlace(new PlaceRequest(Tokens.login).with("selector", "checkoutLoginLink"));
			}
			
		}));
		registerHandler(getView().getBuyAsGiftLink().addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				placeManager.revealPlace(new PlaceRequest(Tokens.gift).with("selector", CheckoutPresenter.SELECTOR));
			}
			
		}));
		
		registerHandler(getView().createEventLink().addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				placeManager.revealPlace(new PlaceRequest(Tokens.createEvent).with("selector", CheckoutPresenter.EVENT_SELECTOR ));
			}
			
		}));
		
		checkoutService.getZones(new AsyncCallback<GWT_Zone[]>() {

			@Override
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onSuccess(GWT_Zone[] result) {
				getView().addZoneOptions(result);
			}
			
		});
		
		
	}
	

	@Override
	public void onReset() {
		super.onReset();
		Log.debug("CheckoutPresenter onReset");
	}
	@Override
	public void onReveal() {
		super.onReveal();
		Log.debug("CheckoutPresenter onReveal");
		this.cardPresenter.getView().setContext("checkout");
		appService.getFullProduct(Integer.parseInt(productID), new AsyncCallback<GWT_Product>() {

			@Override
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onSuccess(GWT_Product result) {
				getView().showPurchase(result);
			}
			
		});
		appService.isLoggedIn(new AsyncCallback<Boolean>() {

			@Override
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onSuccess(Boolean result) {
				if(result)
				{
					//we have a session now we must decide if we should display the checkout form or 
					//cc info if the user already has cards saved
					checkoutService.getUserPaymentOptions(new AsyncCallback<GWT_CreditCard[]>() {
	
						@Override
						public void onFailure(Throwable caught) {
							// TODO Auto-generated method stub
							
						}
	
						@Override
						public void onSuccess(GWT_CreditCard[] paymentDetails) {
							if(paymentDetails!=null && paymentDetails.length>0)
							{
								addToSlot(slot,cardPresenter);
								getView().setupLoggedInWithCards();
							}
							else
								getView().setupLoggedInNoCards();
						}
						
					});
				}
				else
				{//user has no session
					getView().setupCheckoutRegistration();
				}
			}
			
			});
		
	}
}
